home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-01-04 | 39.8 KB | 2,052 lines |
- ;QMouse.s
- ;Written by Dan Babcock
-
- ;This source was assembled with Macro68 release 3.
-
- exeobj
- objfile 'c:QMouse'
- MC68000
- multipass
-
- ;Set INFO_LEVEL to 1 for full debugging output.
- INFO_LEVEL equ 0
-
- ;Put a message to the serial port. Used like so:
- ;
- ;PUTDEBUG <'Init: called'>
- ;
- ;Parameters can be printed out by pushing them on the stack and
- ;adding the appropriate C printf-style % formatting commands.
-
- PUTDEBUG macro ;<msg>
- ifne INFO_LEVEL
- movem.l d0-d1/a0-a1,-(sp)
- lea .msg\@(pc),a0 ;Point to static format string
- lea 16(sp),a1 ;Point to args
- bsr KPutFmt
- movem.l (sp)+,d0-d1/a0-a1
- bra .end\@
- .msg\@:
- dc.b \1,$a,0
- even
- .end\@:
- endc
- endm
-
-
- MAXQUEUE equ 32
- SCREENLISTSIZE equ 32 ;maximum number of screens to keep track of
- POINTERLISTSIZE equ 32
- HANDLERPRI equ 60 ;priority of input.device handler
- TaskPriority equ 21
- ShellPriority equ 0
- MaxCopperSize equ 500
-
- SysBackground equ $e ;offset into gb_copinit copper list
- WindowStart equ $0 ;offset into LOF copper list
- DefColor equ $fff ;white
- WaitLine equ $16
-
- move.l 4,a6
- ;Allocate global data structure
- move.l #Data_Sizeof,d0
- move.l #MEMF_CLEAR,d1
- SYS AllocMem
- tst.l d0
- beq .ErrEnd
- move.l d0,a5
- lea GlobalPtr(pc),a0
- move.l a5,(a0)
-
- ;Allocate chip RAM data.
- move.l #CData_Sizeof,d0
- move.l #MEMF_CLEAR+MEMF_CHIP,d1
- SYS AllocMem
- move.l d0,ChipData(a5)
- beq CleanUp
-
- ;Initialize static data
- move.b #HANDLERPRI,InputInterrupt+LN_PRI(a5)
- move.l a5,InputInterrupt+IS_DATA(a5)
- moveq #1,d0
- move.l d0,ClickCount(a5)
-
- ;Open libraries
- lea LibTable(pc),a2
- move.l a2,a3
- moveq #NumLibs-1,d2
- .OLibLoop:
- move.w (a2)+,a1
- add.l a3,a1
- SYS OldOpenLibrary
- move.w (a2)+,a0
- add.l a5,a0
- move.l d0,(a0)
- beq CleanUp
- dbra d2,.OLibLoop
-
- ;Parse command line
- lea Template(pc),a0
- move.l a0,d1
- lea Options(a5),a0
- move.l a0,d2
- moveq #0,d3 ;no custom rdarg structure
- move.l DosBase(a5),a6
- SYS ReadArgs
- move.l d0,ArgPtr(a5)
- bne .ArgsOK
- lea BadArgs(pc),a0
- move.l a0,d1
- SYS VPrintf
- bra CleanUp
-
- .ErrEnd: moveq #RETURN_FAIL,d0
- rts
-
- .ArgsOK:
- move.l 4,a6
-
- ;Process QUIT option, if selected.
- tst.l QuitOption(a5)
- beq .SkipQuit
- lea ProcName(pc),a1
- SYS FindTask
- tst.l d0
- beq CleanUp
- move.l d0,a1
- move.l TC_Userdata(a1),a0
- move.l QuitSig(a0),d0
- SYS Signal ;tell task to quit
- bsr CleanUp
- bra .Exit
- .SkipQuit:
-
- ;If already installed, kill the existing process.
- lea ProcName(pc),a1
- SYS FindTask
- tst.l d0
- beq .NotInstalled
- move.l d0,a1
- move.l TC_Userdata(a1),a0
- move.l QuitSig(a0),d0
- SYS Signal ;tell task to quit
-
- moveq #26,d2
- .Kill: subq.l #1,d2
- beq .Exit
- move.l DosBase(a5),a6
- moveq #2,d1
- SYS Delay
- lea ProcName(pc),a1
- move.l 4,a6
- SYS FindTask
- tst.l d0
- bne .Kill
- .NotInstalled:
-
- ;Get stack for command.
- move.l DosBase(a5),a6
- SYS Cli
- move.l d0,a0
- move.l cli_DefaultStack(a0),d0
- lsl.l #2,d0
- lea CmdStackSize(pc),a0
- move.l d0,(a0)
- move.l 4,a6
-
- ;Perform relocations.
- lea RelocTable(pc),a0
- lea ResidentCode(a5),a1 ;destination
- lea StartAllocCode(pc),a2
- moveq #NumRelocs-1,d0
- .RLoop: move.w (a0)+,d2
- move.l (a2,d2.w),d1
- add.l a1,d1
- move.l d1,(a2,d2.w)
- dbra d0,.RLoop
-
- ;Copy resident part of code into allocated memory
- lea StartAllocCode(pc),a0 ;source
- ; lea ResidentCode(a5),a1 ;destination
- move.l #ResidentCodeSize,d0 ;size
- SYS CopyMem
- SYS CacheClearU ;for 020/030/040
-
- ;Start a process
- move.l DosBase(a5),a6
- lea ResidentCode(a5),a0
- lea EntryPoint(pc),a1
- move.l a0,(a1)
- lea ProcName-StartAllocCode+ResidentCode(a5),a0
- lea ProcNamePtr(pc),a1
- move.l a0,(a1)
- lea NewProcTags(pc),a0
- move.l a0,d1
- SYS CreateNewProc
-
- ;Exit back to CLI
- .Exit: moveq #0,d0
- rts
-
- RelocTable:
- dc.w reloc1-StartAllocCode
- dc.w reloc2-StartAllocCode
- dc.w reloc3-StartAllocCode
- dc.w reloc4-StartAllocCode
- EndRelocTable:
- NumRelocs equ (EndRelocTable-RelocTable)/2
-
- ***************************************************************************
- * The following code is copied into allocated memory. *
- ***************************************************************************
-
- StartAllocCode:
- move.l 4,a6
- move.l GlobalPtr(pc),a5
- lea IntRoutine(pc),a0
- move.l a0,InputInterrupt+IS_CODE(a5)
-
- ;Initialize damping constant.
- move.l AccelOption(a5),d0
- beq .NoDamp
- move.l d0,a0
- move.l (a0),d0
- subq.l #1,d0
- move.l ThreshOption(a5),d1
- beq .DefThresh
- move.l d1,a0
- move.l (a0),d1
- .DefThresh:
- addq.l #1,d1
- muls.w d0,d1
- move.w d1,DampingConstant(a5)
- .NoDamp:
-
- ;Allocate signals
- moveq #NumSigs-1,d2
- lea Sigs(a5),a2
- .SigLoop: moveq #-1,d0
- SYS AllocSignal
- tst.l d0
- bmi CleanUp
- moveq #0,d1
- bset d0,d1
- move.l d1,(a2)+
- dbra d2,.SigLoop
-
- ;Initialize semaphore(s)
- lea Semaphores(a5),a2
- moveq #NumSemaphores-1,d2
- .InitSema:
- move.l a2,a0
- SYS InitSemaphore
- lea SS_SIZE(a2),a2
- dbra d2,.InitSema
-
- move.l ThisTask(a6),a0
- move.l a0,Task(a5)
- move.l a5,TC_Userdata(a0)
-
- ;Install no-flicker option if selected.
- tst.l FlickerOption(a5)
- beq .NoFlicker
- move.l GraphBase(a5),a0
- move.l gb_copinit(a0),a0
- move.l a0,OriginalCopInit(a5)
- move.l ChipData(a5),a1
- lea Copper(a1),a1
- move.l a1,a2
- move.w #MaxCopperSize/4-1,d0
- .CLoop: move.l (a0)+,d1
- cmp.l #$008A0000,d1
- beq .CopEnd
- move.l d1,(a1)+
- dbra d0,.CLoop
- clr.l FlickerOption(a5)
- bra .NoFlicker
- .CopEnd: move.l #$01800000,(a1)+
- move.l a1,WaitLineAddress(a5)
- move.l #$1607FFFE,(a1)+
- move.w #$0180,(a1)+
- move.l #$008A0000,2(a1)
- move.l a1,RealBackground(a5)
- move.l a2,cop1lc+_custom
- move.l GraphBase(a5),a0
- move.l a2,gb_copinit(a0)
- cmp.w #color,SysBackground-2(a2)
- bne .DefColor
- move.w SysBackground(a2),(a1)
- bra .NoFlicker
- .DefColor:
- move.w #DefColor,(a1)
- .NoFlicker:
-
- ;Patch MANY system routines.
- SYS Forbid
- lea PatchTable(pc),a2
- move.l a2,a3
- .Patch: move.w (a2)+,d0 ;get base
- beq .EndPatch
- move.l (a5,d0.w),a1 ;library base to patch
- move.w (a2)+,d0 ;get minimum library version
- cmp.w LIB_VERSION(a1),d0
- bls .VersionOK
- addq.l #6,a2
- bra .Patch
- .VersionOK:
- move.w (a2)+,d0 ;get offset to new routine
- lea (a3,d0.w),a0
- move.l a0,d0 ;new routine address
- move.w (a2)+,a0 ;_LVO offset
- SYS SetFunction
- move.w (a2)+,d1
- move.l d0,(a5,d1.w)
- bra .Patch
- .EndPatch:
- SYS Permit
-
- ;Create an IORequest structure
- SYS CreateMsgPort
- move.l d0,InputMsgPort(a5)
- beq CleanUp
- move.l d0,a0
- moveq #IOSTD_SIZE,d0
- SYS CreateIORequest
- move.l d0,InputIORequest(a5)
- beq CleanUp
-
- ;Perform NoClick, if desired.
- move.l NoClickOption(a5),d2
- beq .Click
- move.l d2,a0
- move.l (a0),d2
- .Click: moveq #0,d3
- moveq #3,d4
- .ClickLoop:
- lea TrackName(pc),a0 ;device name
- move.l d3,d0 ;unit number
- move.l InputIORequest(a5),a1 ;IO request
- moveq #0,d1 ;flags
- SYS OpenDevice
- tst.l d0
- bne .ECLoop
- move.l InputIORequest(a5),a1 ;IO request
- move.l IO_UNIT(a1),a0
- btst d3,d2
- beq .SkipNoClick
- bset #TDPB_NOCLICK,TDU_PUBFLAGS(a0)
- .SkipNoClick:
- tst.l VerifyOption(a5)
- beq .NoVerify
- bset #1,TDU_PUBFLAGS(a0)
- .NoVerify:
- tst.l NoVerifyOption(a5)
- beq .SkipVerify
- bclr #1,TDU_PUBFLAGS(a0)
- .SkipVerify:
- SYS CloseDevice
- .ECLoop: addq.l #1,d3
- dbra d4,.ClickLoop
-
- ;Handle 'STAR' option.
- tst.l StarOption(a5)
- beq .NoStar
- move.l DosBase(a5),a0
- move.l dl_Root(a0),a0
- bset #0,rn_Flags(a0)
- .NoStar:
-
- ;Open the input.device
- lea InputName(pc),a0 ;device name
- moveq #0,d0 ;unit number
- move.l InputIORequest(a5),a1 ;IO request
- moveq #0,d1 ;flags
- SYS OpenDevice
- tst.l d0
- bne CleanUp
-
- ;Install virtical blank routine if needed.
- tst.l SunMouseOption(a5)
- beq .SkipVBL
- moveq #INTB_VERTB,d0
- lea VBlankServer(a5),a1
- move.l a5,IS_DATA(a1)
- lea VBlankRoutine(pc),a0
- move.l a0,IS_CODE(a1)
- move.b #NT_INTERRUPT,LN_TYPE(a1)
- SYS AddIntServer
- bset #STB_IntInstalled,Status(a5)
- .SkipVBL:
-
- ;Install input handler
- move.l InputIORequest(a5),a1
- move.w #IND_ADDHANDLER,IO_COMMAND(a1)
- lea InputInterrupt(a5),a0
- move.l a0,IO_DATA(a1)
- SYS DoIO
- tst.l d0
- bne CleanUp
- st HandlerInstalled(a5)
-
- ;Wait for signal(s)
- Wait:
- tst.l TaskQueue(a5)
- bne .DoTasks
- lea Sigs(a5),a0
- move.l (a0)+,d0
- moveq #NumSigs-2,d1
- .. add.l (a0)+,d0
- dbra d1,..
- move.l 4,a6
- SYS Wait
- move.l d0,d7
- move.l d7,d1
- and.l QuitSig(a5),d1
- bne SafeCleanUp
- move.l d7,d1
- and.l FuncSig(a5),d1
- beq Wait
- .DoTasks: move.l IntBase(a5),a6
- lea TaskQueue(a5),a4
- .TaskLoop:
- move.l (a4),d0
- beq Wait
- clr.l (a4)+
- move.l d0,a0
- bsr GetAllSemaphores
- jsr (a0)
- bsr FreeAllSemaphores
- bra .TaskLoop
-
- BlankScreenTags:
- dc.l SA_Depth,1
- dc.l SA_Colors
- reloc4: dc.l .ColorSpec-StartAllocCode
- dc.l 0 ;end tags
- .ColorSpec:
- dc.w 0,0,0,0
- dc.w 1,0,0,0
- dc.w -1
- BlankScreenWindowTags:
- dc.l WA_CustomScreen
- BlankScreenTagPtr:
- dc.l 0
- dc.l 0 ;end tags
-
- DoBlankScreen:
- move.l BlankScreenPtr(a5),d0
- beq .Blank
- move.l d0,a0
- SYS ScreenToFront
- move.l BlankScreenWindowPtr(a5),d0
- beq _RTS1
- move.l d0,a0
- jmp _LVOActivateWindow(a6)
- .Blank: sub.l a0,a0
- lea BlankScreenTags(pc),a1
- SYS OpenScreenTagList
- move.l d0,BlankScreenPtr(a5)
- beq _RTS1
- lea BlankScreenTagPtr(pc),a0
- move.l d0,(a0)
- sub.l a0,a0
- lea BlankScreenWindowTags(pc),a1
- SYS OpenWindowTagList
- move.l d0,BlankScreenWindowPtr(a5)
- beq _RTS1
- move.l d0,a0
- move.l ChipData(a5),a1
- ; lea ZeroMouse(a1),a1 ;not needed
- moveq #1,d0 ;height
- moveq #16,d1 ;width
- moveq #0,d2 ;xoffset
- moveq #0,d3 ;yoffset
- pea DoBlankScreen(pc)
- move.l OldSetPointer(a5),-(sp)
- _RTS1: rts
-
-
- DoRestoreScreen:
- move.l BlankScreenPtr(a5),d2
- beq _RTS1
- clr.l BlankScreenPtr(a5)
- move.l BlankScreenWindowPtr(a5),d0
- beq .SkipWinClose
- clr.l BlankScreenWindowPtr(a5)
- move.l d0,a0
- SYS CloseWindow
- .SkipWinClose:
- move.l d2,a0
- jmp _LVOCloseScreen(a6)
-
-
- CTF: bsr GetWindow
- tst.l d0
- beq _RTS1
- move.l CTFOption(a5),a2
- move.l (a2),d1
- cmp.l #1,d1
- bhi .MoreThanOne
- bra DoWindowToFront
- .MoreThanOne:
- cmp.l ClickWindow(a5),d0
- beq .SameWindow
- move.l d0,ClickWindow(a5)
- moveq #1,d0
- move.l d0,ClickCount(a5)
- .Time: bsr GetIBase
- move.l ib_Seconds(a6),ClickTime+TV_SECS(a5)
- move.l ib_Micros(a6),ClickTime+TV_MICRO(a5)
- bra FreeIBase
- .SameWindow:
-
- ;Check to see whether MaxClickDelay has been exceeded. If not, increment
- ;ClickCount and compare with (CTFOption). If equal, do a WindowToFront.
- ;Window under pointer in D0.
-
- push d0
- move.l ClickTime+TV_SECS(a5),d0
- move.l ClickTime+TV_MICRO(a5),d1
- bsr GetIBase
- move.l ib_Seconds(a6),d2
- move.l ib_Micros(a6),d3
- bsr FreeIBase
- SYS DoubleClick
- tst.l d0
- beq .TimeExceeded
- addq.l #1,ClickCount(a5)
- move.l CTFOption(a5),a0
- move.l (a0),d0
- cmp.l ClickCount(a5),d0
- bhi .NeedMoreClicks
- clr.l ClickCount(a5)
- pop d0
- bra DoWindowToFront
- .TimeExceeded:
- moveq #1,d0
- move.l d0,ClickCount(a5)
- .NeedMoreClicks:
- pop d0
- bra .Time
-
- CTB: bsr GetWindow
- tst.l STBOption(a5)
- bne .FlipScreen
- tst.l d0
- beq .FlipScreen
- move.l d0,a1
- move.l wd_Flags(a1),d2
- and.l #WFLG_BACKDROP,d2
- bne .FlipScreen
-
- ;Is this the only window on this screen, except for backdrop windows?
- move.l wd_WScreen(a1),a1
- move.l sc_FirstWindow(a1),a1
- .BackLoop:
- cmp.l a1,d0
- beq .EBackLoop
- move.l wd_Flags(a1),d2
- and.l #WFLG_BACKDROP,d2
- beq .FlipWindow
- .EBackLoop:
- move.l (a1),a1
- move.l a1,d2
- bne .BackLoop
- .FlipScreen:
- tst.l d1
- beq .End
- move.l d1,a0
- jmp _LVOScreenToBack(a6)
- .FlipWindow:
- move.l d0,a0
- jmp _LVOWindowToBack(a6)
- .End: rts
-
- PopCLI:
- ;Execute the desired command
- move.l a6,-(sp)
- move.l DosBase(a5),a6
- move.l CmdOption(a5),d1
- beq .End
- lea .Tags(pc),a0
- move.l a0,d2 ;tags
-
- ;Important fix: free the semaphores (we don't need them here and they can and
- ;do lead to deadlocks).
- bsr FreeAllSemaphores
- SYS SystemTagList
- bsr GetAllSemaphores
-
- tst.l NoWBenchToFrontOption(a5)
- bne .End
- move.l IntBase(a5),a6
- SYS WBenchToFront
- .End: move.l (sp)+,a6
- rts
-
- .Tags: dc.l SYS_UserShell,0
- dc.l NP_Priority,ShellPriority
- dc.l NP_StackSize
- CmdStackSize:
- dc.l 0
- dc.l 0 ;end of tag list
-
- SafeCleanUp:
- ;Make sure the SetFunction'ed vectors are still intact.
- lea PatchTable(pc),a0
- move.l a0,a2
- .Safe: move.w (a0)+,d0
- beq CleanUp
- move.l (a5,d0.w),a1 ;library base
- addq.l #2,a0 ;skip version #
- move.w (a0)+,d0
- lea (a2,d0.w),a3 ;address of new routine
- move.w (a0)+,d0 ;_LVO offset
- move.w (a0)+,d1 ;Old vector
- tst.l (a5,d1.w)
- beq .Safe
- cmp.l 2(a1,d0.w),a3
- beq .Safe
-
- ;A routine has been patched by another program. Alert the user.
- ;a1 is lib pointer, d0.w is routine offset.
-
- ext.l d0
- neg.l d0
- move.l d0,-(sp)
- move.l LN_NAME(a1),-(sp)
- move.l sp,a3
- move.l IntBase(a5),a6
- sub.l a0,a0
- lea PatchAlert(pc),a1
- sub.l a2,a2
- SYS EasyRequestArgs
- addq.l #8,sp
- bra Wait
- PatchAlert:
- dc.l es_SIZEOF
- dc.l 0
- reloc1: dc.l TitleText-StartAllocCode
- reloc2: dc.l AlertText-StartAllocCode
- reloc3: dc.l OkayText-StartAllocCode
- TitleText:
- dc.b 'QMouse message',0
- AlertText:
- dc.b 'Can''t quit or modify parameters. Another program',$a
- dc.b 'has patched the same OS routines!',$a
- dc.b $a
- dc.b 'Technical information:',$a
- dc.b 'Library: %s',$a
- dc.b 'Offset: -$%lx',$a
- dc.b '(There may be others)',0
- OkayText:
- dc.b 'OK',0
- even
-
- CleanUp:
-
- ;Enter with global ptr in A5
-
- move.l 4,a6
-
- ;Remove interrupt routine, if installed.
- btst #STB_IntInstalled,Status(a5)
- beq .SkipIntRemove
- moveq #INTB_VERTB,d0
- lea VBlankServer(a5),a1
- SYS RemIntServer
- .SkipIntRemove:
-
- ;Remove input handler, if installed.
- tst.b HandlerInstalled(a5)
- beq .SkipHand
- move.l InputIORequest(a5),a1
- move.w #IND_REMHANDLER,IO_COMMAND(a1)
- lea InputInterrupt(a5),a0
- move.l a0,IO_DATA(a1)
- SYS DoIO
- .SkipHand:
-
- tst.l OldCloseScreen(a5)
- beq .SkipRestore
-
- bsr RestoreMouse
- move.l IntBase(a5),a6
- bsr DoRestoreScreen
- move.l 4,a6
-
- ;Restore original vectors.
-
- lea PatchTable(pc),a2
- .RestoreVecs:
- move.w (a2),d0
- beq .SkipRestore
- addq.l #6,a2 ;skip new routine info
- move.l (a5,d0.w),a1 ;get library base
- move.w (a2)+,a0 ;get _LVO
- move.w (a2)+,d0
- move.l (a5,d0.w),d0 ;old routine
- beq .RestoreVecs
- SYS SetFunction
- bra .RestoreVecs
- .SkipRestore:
-
- ;Delay for 1/10 second to ensure that no-one is using the patch code.
- move.l DosBase(a5),d0
- beq .SkipFreeArg
- move.l d0,a6
- moveq #5,d1
- SYS Delay
-
- ;Free argument structure
- move.l ArgPtr(a5),d1
- beq .SkipFreeArg
- SYS FreeArgs
- .SkipFreeArg:
-
- move.l 4,a6
-
- ;Free signals
- lea Sigs(a5),a2
- moveq #NumSigs-1,d2
- .SigLoop: move.l (a2)+,d1
- beq .NextSig
- moveq #-1,d0
- .BitLoop: addq.l #1,d0
- btst d0,d1
- beq .BitLoop
- SYS FreeSignal
- .NextSig: dbra d2,.SigLoop
-
- ;Remove flicker option, if selected.
- tst.l FlickerOption(a5)
- beq .SkipFlicker
- move.l OriginalCopInit(a5),a0
- move.l GraphBase(a5),a2
- move.l gb_copinit(a2),a1
- .CLoop: move.l (a1)+,(a0)+
- cmp.l #$008A0000,(a0)
- bne .CLoop
- move.l OriginalCopInit(a5),gb_copinit(a2)
- move.l OriginalCopInit(a5),cop1lc+_custom
- .SkipFlicker:
-
- ;Close libraries
- lea LibTable+2(pc),a2
- moveq #NumLibs-1,d2
- .CLibLoop:
- move.w (a2),a0
- add.l a5,a0
- tst.l (a0)
- beq .SkipClose
- move.l (a0),a1
- SYS CloseLibrary
- .SkipClose:
- addq.l #4,a2
- dbra d2,.CLibLoop
-
- ;Close input.device
- move.l InputIORequest(a5),d0
- beq .SkipCloseDev
- move.l d0,a1
- tst.b IO_ERROR(a1) ;was there an error?
- bne .SkipCloseDev ;yes, don't close
- SYS CloseDevice
- .SkipCloseDev:
-
- ;Delete IORequest structure
- move.l InputIORequest(a5),a0
- SYS DeleteIORequest
- move.l InputMsgPort(a5),a0
- SYS DeleteMsgPort
-
- ;Free chip data.
- move.l ChipData(a5),d0
- beq .SkipChipData
- move.l d0,a1
- move.l #CData_Sizeof,d0
- SYS FreeMem
- .SkipChipData:
-
- ;Deallocate global structure. Note that this code is (sometimes) executed
- ;within the memory that we are freeing, so we are careful to terminate with
- ;a JMP.
- move.l a5,a1
- move.l #Data_Sizeof,d0
- jmp _LVOFreeMem(a6)
-
- ;Semaphore routines
-
- GetIBase:
- ; PUTDEBUG <'GetIBase: Called'>
- movem.l d0-d1/a0-a1/a5-a6,-(sp)
- move.l GlobalPtr(pc),a5
- move.l IntBase(a5),a6
- moveq #0,d0
- SYS LockIBase
- move.l d0,IBaseLock(a5)
- movem.l (sp)+,d0-d1/a0-a1/a5-a6
- ; PUTDEBUG <'GetIBase: Done'>
- rts
- FreeIBase:
- ; PUTDEBUG <'FreeIBase'>
- movem.l d0-d1/a0-a1/a6,-(sp)
- move.l GlobalPtr(pc),a0
- move.l IntBase(a0),a6
- move.l IBaseLock(a0),a0
- SYS UnlockIBase
- movem.l (sp)+,d0-d1/a0-a1/a6
- rts
-
-
- GetSemaphore:
- PUTDEBUG <'GetSemaphore: Called'>
- movem.l a0/a6,-(sp)
- move.l GlobalPtr(pc),a0
- lea MySemaphore(a0),a0
- _GS: move.l 4,a6
- SYS ObtainSemaphore
- movem.l (sp)+,a0/a6
- PUTDEBUG <'GetSemaphore: Done'>
- rts
- FreeSemaphore:
- movem.l a0/a6,-(sp)
- move.l GlobalPtr(pc),a0
- lea MySemaphore(a0),a0
- _FS: move.l 4,a6
- SYS ReleaseSemaphore
- movem.l (sp)+,a0/a6
- PUTDEBUG <'FreeSemaphore'>
- rts
-
- GetCloseWindowSemaphore:
- PUTDEBUG <'GetCloseWindowSemaphore'>
- movem.l a0/a6,-(sp)
- move.l GlobalPtr(pc),a0
- lea CloseWindowSemaphore(a0),a0
- bra _GS
- FreeCloseWindowSemaphore:
- PUTDEBUG <'FreeCloseWindowSemaphore'>
- movem.l a0/a6,-(sp)
- move.l GlobalPtr(pc),a0
- lea CloseWindowSemaphore(a0),a0
- bra _FS
-
- GetCloseScreenSemaphore:
- PUTDEBUG <'GetCloseScreenSemaphore'>
- movem.l a0/a6,-(sp)
- move.l GlobalPtr(pc),a0
- lea CloseScreenSemaphore(a0),a0
- bra _GS
- FreeCloseScreenSemaphore:
- PUTDEBUG <'FreeCloseScreenSemaphore'>
- movem.l a0/a6,-(sp)
- move.l GlobalPtr(pc),a0
- lea CloseScreenSemaphore(a0),a0
- bra _FS
-
- GetCloseWBSemaphore:
- PUTDEBUG <'GetCloseWBSemaphore'>
- movem.l a0/a6,-(sp)
- move.l GlobalPtr(pc),a0
- lea CloseWBSemaphore(a0),a0
- bra _GS
- FreeCloseWBSemaphore:
- PUTDEBUG <'FreeCloseWBSemaphore'>
- movem.l a0/a6,-(sp)
- move.l GlobalPtr(pc),a0
- lea CloseWBSemaphore(a0),a0
- bra _FS
-
- GetAllSemaphores:
- ;The order matters! The sems must be allocated in this order to avoid
- ;the "deadly embrace".
- bsr GetCloseWBSemaphore
- bsr GetCloseScreenSemaphore
- bsr GetCloseWindowSemaphore
- bra GetSemaphore
- FreeAllSemaphores:
- ;We can free in any order (provided that we are freeing ALL of them).
- bsr FreeSemaphore
- bsr FreeCloseWindowSemaphore
- bsr FreeCloseScreenSemaphore
- bra FreeCloseWBSemaphore
-
-
- LibTable: dc.w DosName-LibTable
- dc.w DosBase
- dc.w IntName-LibTable
- dc.w IntBase
- dc.w LayersName-LibTable
- dc.w LayersBase
- dc.w GraphName-LibTable
- dc.w GraphBase
- dc.w UtilityName-LibTable
- dc.w _UtilityBase
- EndLibTable:
-
- NumLibs equ (EndLibTable-LibTable)/4
-
- ;****************** SetFunction'ed routines ***************
-
- patch macro
- dc.w \1
- dc.w \3 ;minimum library version
- dc.w New\2-PatchTable
- dc.w _LVO\2
- dc.w Old\2
- endm
-
- PatchTable:
- patch IntBase,SetWindowPointerA,39
- patch IntBase,OpenWindowTagList,39
- patch IntBase,CloseScreen,37
- patch IntBase,CloseWorkBench,37
- patch IntBase,CloseWindow,37
- patch IntBase,SetPointer,37
- patch IntBase,ClearPointer,37
- patch IntBase,DisplayBeep,37
- dc.w 0
-
- NewDisplayBeep:
- PUTDEBUG <'NewDisplayBeep'>
- move.l GlobalPtr(pc),a1
- tst.l BeepOption(a1)
- bne .SkipBeep
- move.l OldDisplayBeep(a1),-(sp)
- .SkipBeep:
- rts
-
- NewOpenWindowTagList:
- ;Enter with NewWindow in A0, taglist in A1
- PUTDEBUG <'NewOpenWindowTagList'>
- move.l a1,-(sp)
- pea .HandlePointer(pc)
- subq.l #8,sp
- move.l a0,(sp)
- move.l GlobalPtr(pc),a0
- move.l OldOpenWindowTagList(a0),4(sp)
- move.l (sp)+,a0
- .End: rts
- .RestoreD0:
- move.l (sp)+,d0
- rts
- .HandlePointer:
- move.l (sp)+,a1
- tst.l d0
- beq .End
- move.l d0,a0
- move.l d0,-(sp)
- pea .RestoreD0(pc)
- ; bra NewSetWindowPointerA
-
- NewSetWindowPointerA:
- ;Enter with:
- ;A0 - Window
- ;A1 - taglist
-
- SaveRegs setrl d4-d5/a0-a6
-
- PUTDEBUG <'NewSetWindowPointerA'>
- bsr GetSemaphore
- movem.l SaveRegs,-(sp)
- move.l GlobalPtr(pc),a5
- lea PointerList(a5),a2
-
- ;Find if window is already in table and find empty spot.
- moveq #POINTERLISTSIZE-1,d4
- sub.l a3,a3
- .WinSearch:
- move.l pt_Window(a2),d5
- bne .SkipSave
- move.l a2,a3
- .SkipSave:
- cmp.l d5,a0
- beq .Found
- lea pt_Sizeof(a2),a2
- dbra d4,.WinSearch
- move.l a3,a2
- move.l a2,d4
- beq .CallOld ;no room in table, so forget it
- .Found:
- ;Store the taglist information
- move.l a0,a3 ;window
- move.l a1,a4 ;taglist
- move.l a0,pt_Window(a2)
- st TagVersion(a2)
- move.l _UtilityBase(a5),a6
- ;Check for WA_BusyPointer.
- move.l #WA_BusyPointer,d0
- move.l a4,a0
- SYS FindTagItem
- tst.l d0
- beq .NotBusy
- move.l d0,a0
-
- IFNE INFO_LEVEL
- move.l 4(a0),-(sp)
- move.l (a0),-(sp)
- PUTDEBUG <'WA_BusyPointer=%lx,%lx '>
- addq.l #8,sp
- ENDC
-
- move.l (a0),(a2)
- move.l 4(a0),4(a2)
- beq .NotBusy
- clr.l 8(a2)
- bra .CallOld
- .NotBusy:
- ;Check for WA_Pointer.
- move.l #WA_Pointer,d0
- move.l a4,a0
- SYS FindTagItem
- tst.l d0
- beq .Nothing
- move.l d0,a0
-
- IFNE INFO_LEVEL
- move.l 4(a0),-(sp)
- move.l (a0),-(sp)
- PUTDEBUG <'WA_Pointer=%lx,%lx '>
- addq.l #8,sp
- ENDC
-
- move.l (a0),(a2)
- move.l 4(a0),4(a2)
- clr.l 8(a2)
- bra .CallOld
- .Nothing:
- ;Don't understand the taglist.
- PUTDEBUG <'Don''t grok SetWindowPointerA taglist!'>
- clr.l pt_Window(a2)
- .CallOld: cmp.l MBlankWindow(a5),a3
- beq .End
- ;Call old SetWindowPointerA
- movem.l (sp)+,SaveRegs
- subq.l #8,sp
- move.l a0,(sp)
- move.l GlobalPtr(pc),a0
- move.l OldSetWindowPointerA(a0),4(sp)
- move.l (sp)+,a0
- bra FreeSemaphore
- .End: movem.l (sp)+,SaveRegs
- bra FreeSemaphore
-
- NewSetPointer:
- PUTDEBUG <'NewSetPointer'>
- bsr GetSemaphore
- movem.l d4-d5/a2-a3/a5,-(sp)
- move.l GlobalPtr(pc),a5
- cmp.l ChipData(a5),a1 ;special check to ward off sneaky code like
- beq .End1 ;reqtools
- lea PointerList(a5),a2
-
- ;Find if window is already in table and find empty spot.
- moveq #POINTERLISTSIZE-1,d4
- sub.l a3,a3
- .WinSearch:
- move.l pt_Window(a2),d5
- bne .SkipSave
- move.l a2,a3
- .SkipSave:
- cmp.l d5,a0
- beq .Found
- lea pt_Sizeof(a2),a2
- dbra d4,.WinSearch
- move.l a3,a2
- move.l a2,d4
- beq .End ;no room in table, so forget it
- .Found: movem.l d0-d3/a0-a1,(a2)
- clr.b TagVersion(a2)
- .End: cmp.l MBlankWindow(a5),a0
- beq .End1
- movem.l (sp)+,d4-d5/a2-a3/a5
- subq.l #8,sp
- move.l a0,(sp)
- move.l GlobalPtr(pc),a0
- move.l OldSetPointer(a0),4(sp)
- move.l (sp)+,a0
- bra FreeSemaphore
- .End1: movem.l (sp)+,d4-d5/a2-a3/a5
- bra FreeSemaphore
-
- NewClearPointer:
- PUTDEBUG <'NewClearPointer'>
- bsr GetSemaphore
- move.l GlobalPtr(pc),a1
- lea PointerList(a1),a1
- moveq #POINTERLISTSIZE-1,d0
- .ClearLoop:
- cmp.l pt_Window(a1),a0
- beq .Found
- lea pt_Sizeof(a1),a1
- dbra d0,.ClearLoop
- bra .End
- .Found: clr.l pt_Window(a1)
- .End: move.l GlobalPtr(pc),a1
- cmp.l MBlankWindow(a1),a0
- beq .End1
- move.l OldClearPointer(a1),-(sp)
- .End1: bra FreeSemaphore
-
- NewCloseWorkBench:
- PUTDEBUG <'NewCloseWorkBench'>
- bsr GetCloseWBSemaphore
- SYS OpenWorkBench ;get workbench screen ptr in d0
- tst.l d0
- beq FreeCloseWBSemaphore
- move.l d0,a0
- move.l GlobalPtr(pc),a1
- move.l OldCloseWorkBench(a1),d1
- pea .Free(pc)
- bra CloseScreenCode
- .Free: bra FreeCloseWBSemaphore
-
- NewCloseScreen:
- PUTDEBUG <'NewCloseScreen'>
- bsr GetCloseScreenSemaphore
- move.l GlobalPtr(pc),a1
- move.l OldCloseScreen(a1),d1
- pea .Free(pc)
- bra CloseScreenCode
- .Free: bra FreeCloseScreenSemaphore
-
- CloseScreenCode:
- ;Code shared by NewCloseScreen and NewCloseWorkBench
- ;Enter with Screen in A0, Global in A1, old vector in D1
-
- bsr GetSemaphore
- lea ScreenList(a1),a1
- moveq #SCREENLISTSIZE-1,d0
- .Loop: cmp.l (a1),a0
- beq .Match
- addq.l #8,a1
- dbra d0,.Loop
- .End: bsr FreeSemaphore
- move.l GlobalPtr(pc),a1
- pea .ExtraClose(pc)
- move.l d1,-(sp)
- rts
- .Match: clr.l (a1)
- bra .End
- .ExtraClose:
- move.l GlobalPtr(pc),a0
- bsr GetIBase
- move.l ib_FirstScreen(a6),CurrentTopScreen(a0)
- move.l ib_ActiveScreen(a6),CurrentActiveScreen(a0)
- bsr FreeIBase
- bra RestoreWindow
-
- NewCloseWindow:
- PUTDEBUG <'NewCloseWindow'>
- move.l GlobalPtr(pc),a1
- bsr GetCloseWindowSemaphore
- bsr GetSemaphore
- pea .ExtraClose(pc)
- push a0
- SYS ClearPointer
- pop a0
- move.l GlobalPtr(pc),a1
- cmp.l MBlankWindow(a1),a0
- bne .SkipClearMBW
- clr.l MBlankWindow(a1)
- .SkipClearMBW:
- cmp.l ClickWindow(a1),a0
- bne .SkipClearCW
- clr.l ClickWindow(a1)
- .SkipClearCW:
- lea ScreenList+4(a1),a1
- moveq #SCREENLISTSIZE-1,d0
- .Loop: cmp.l (a1),a0
- beq .Match
- addq.l #8,a1
- dbra d0,.Loop
- .End: bsr FreeSemaphore
- move.l GlobalPtr(pc),a1
- move.l OldCloseWindow(a1),-(sp)
- rts
- .Match: clr.l -4(a1)
- bra .End
- .ExtraClose:
- move.l GlobalPtr(pc),a0
- bsr GetIBase
- move.l ib_ActiveWindow(a6),CurrentActiveWindow(a0)
- bsr FreeIBase
- bra FreeCloseWindowSemaphore
-
- ;****************** End of SetFunction'ed routines ***************
-
- RememberWindow:
-
- ;No OS calls
- ;Enter with Screen in A0, Window in A2
-
- movem.l d0-d1/a0-a2/a5,-(sp)
- move.l GlobalPtr(pc),a5
-
- ;Sanity checks
- move.l a0,d0
- beq .End
- move.l a2,d0
- beq .End
-
- lea ScreenList(a5),a1
- moveq #SCREENLISTSIZE-1,d0
- .ScLoop: cmp.l (a1),a0
- beq .Match
- addq.l #8,a1
- dbra d0,.ScLoop
-
- ;Screen not found. Add to screen list.
- lea ScreenList(a5),a1
- moveq #SCREENLISTSIZE-1,d0
- .AddLoop: tst.l (a1)
- beq .Match
- addq.l #8,a1
- dbra d0,.AddLoop
- bra .End ;table is full
- .Match:
- move.l a0,(a1)+ ;screen
- move.l a2,(a1) ;currently activated window
- .End: movem.l (sp)+,d0-d1/a0-a2/a5
- rts
-
- RestoreWindow:
- movem.l a1-a2,-(sp)
- move.l GlobalPtr(pc),a1
- lea TaskRestoreWindow(pc),a2
- bsr DoFunc
- movem.l (sp)+,a1-a2
- rts
-
- TaskRestoreWindow:
-
- ;This routine restores (re-activates) the previously activated window for
- ;this screen.
-
- movem.l d0-d2/a0-a2/a6,-(sp)
- move.l GlobalPtr(pc),a0
- tst.l NoActivateOption(a0)
- bne .End
- lea ScreenList(a0),a2
- move.l IntBase(a0),a6
- bsr GetIBase
- move.l ib_FirstScreen(a6),d2
- bsr FreeIBase
- tst.l d2
- beq .End ;sanity check
- move.l d2,CurrentTopScreen(a0)
- tst.l PubChangeOption(a0)
- beq .NoPubChange
-
- ;If the screen is public, make it the default public screen.
-
- SYS LockPubScreenList
- .PubLoop: tst.l d0
- beq .EndPubChange
- move.l d0,a0
- cmp.l psn_Screen(a0),d2
- beq .FoundScreen
- move.l LN_SUCC(a0),d0
- bra .PubLoop
- .FoundScreen:
- move.l LN_NAME(a0),a0
- SYS SetDefaultPubScreen
-
- .EndPubChange:
- SYS UnlockPubScreenList
- .NoPubChange:
- move.l d2,a0
- moveq #SCREENLISTSIZE-1,d0
- .Loop: cmp.l (a2),a0
- beq .Match
- addq.l #8,a2
- dbra d0,.Loop
- move.l sc_FirstWindow(a0),a0 ;default window
- move.l a0,d0
- beq .End ;sanity check
- bra .SkipMatch
- .Match:
- move.l 4(a2),a0
- .SkipMatch:
- SYS ActivateWindow
- move.l GlobalPtr(pc),a0
- bsr GetIBase
- move.l ib_ActiveScreen(a6),CurrentActiveScreen(a0)
- bsr FreeIBase
- .End: movem.l (sp)+,d0-d2/a0-a2/a6
- rts
-
-
- ;Get window associated with current mouse position.
- ;Returns Window in D0 and screen in D1.
-
- GetWindow:
- movem.l d4/a0-a1/a4-a6,-(sp)
- move.l GlobalPtr(pc),a5
- move.l LayersBase(a5),a6
- move.l IntBase(a5),a4
- bsr GetIBase
- move.l ib_FirstScreen(a4),d4
- .ScLoop: tst.l d4
- beq .ErrEnd
- move.l d4,a0
- move.l sc_NextScreen(a0),d4
- move.w sc_MouseX(a0),d0
- bmi .ScLoop
- move.w sc_MouseY(a0),d1
- bmi .ScLoop
- push a0
- lea sc_LayerInfo(a0),a0
- bsr FreeIBase
- SYS WhichLayer
- pop d1
- tst.l d0
- beq .End
- move.l d0,a0
- move.l lr_Window(a0),d0
- .End: movem.l (sp)+,d4/a0-a1/a4-a6
- rts
- .ErrEnd: bsr FreeIBase
- moveq #0,d0
- moveq #0,d1
- bra .End
-
- ActivateWindow:
-
- ;Activate the window under the mouse pointer.
- ;Enter with IntuitionBase in A6
-
- bsr GetWindow
- tst.l d0
- beq .End
- move.l d0,a0
- bsr GetIBase
- move.l ib_ActiveWindow(a6),d0
- bsr FreeIBase
- cmp.l d0,a0
- beq .End
- tst.l wd_FirstRequest(a0)
- bne .End
- SYS ActivateWindow
- .End: rts
-
- DoWindowToFront:
-
- ;Perform a WindowToFront on the window in D0.
- ;Enter with IntuitionBase in A6.
-
- tst.l d0
- beq .End1
- movem.l d0-d1/a0-a1/a6,-(sp)
- move.l d0,a0
- move.l wd_WLayer(a0),a1
- move.l a1,d0
- beq .End
- move.l lr_ClipRect(a1),a1
- move.l a1,d0
- beq .End
- tst.l (a1)
- beq .End
- move.l wd_Flags(a0),d0
- and.l #WFLG_BACKDROP,d0
- bne .End
- SYS WindowToFront
- .End: movem.l (sp)+,d0-d1/a0-a1/a6
- .End1: rts
-
- BlankMouse:
- movem.l d0-d3/a0-a1/a5-a6,-(sp)
- move.l GlobalPtr(pc),a5
- move.l IntBase(a5),a6
- bsr GetIBase
- move.l ib_ActiveWindow(a6),d0
- bsr FreeIBase
- tst.l d0
- beq .End
- cmp.l MBlankWindow(a5),d0
- beq .End
- bsr RestoreMouse
- move.l d0,MBlankWindow(a5)
- move.l d0,a0
- move.l ChipData(a5),a1
- ; lea ZeroMouse(a1),a1 ;not needed
- moveq #1,d0 ;height
- moveq #16,d1 ;width
- moveq #0,d2 ;xoffset
- moveq #0,d3 ;yoffset
- pea .End(pc)
- move.l OldSetPointer(a5),-(sp)
- rts
- .End: movem.l (sp)+,d0-d3/a0-a1/a5-a6
- rts
-
- RestoreMouse:
- movem.l d0-d1/a0-a2/a5-a6,-(sp)
- move.l GlobalPtr(pc),a5
- move.l IntBase(a5),a6
- move.l MBlankWindow(a5),d0
- beq .End
-
- ;Look for window in pointer table. If present, do a SetPointer or SetWindowPointerA
- ;to restore the custom pointer. Otherwise call ClearPointer.
-
- move.l d0,a0
- clr.l MBlankWindow(a5)
- lea PointerList(a5),a1
- moveq #POINTERLISTSIZE-1,d0
- .WinLoop: cmp.l pt_Window(a1),a0
- beq .Found
- lea pt_Sizeof(a1),a1
- dbra d0,.WinLoop
- pea .End(pc)
- move.l OldClearPointer(a5),-(sp)
- rts
- .End: movem.l (sp)+,d0-d1/a0-a2/a5-a6
- rts
- .Found: move.l a1,a2
- tst.b TagVersion(a2)
- beq .NoTag
- ;Call SetWindowPointerA to restore the custom pointer.
- move.l pt_Window(a2),a0
- pea .End(pc)
- move.l OldSetWindowPointerA(a5),-(sp)
- rts
- .NoTag: movem.l (a2),d0-d3/a0-a1
- pea .End(pc)
- move.l OldSetPointer(a5),-(sp)
- rts
-
- ;***************************************************************************
- ;Start of input handler code
- ;***************************************************************************
-
- BlankScreen:
-
- ;Enter with global in A1.
- bset #STB_SBlanked,Status(a1)
- lea DoBlankScreen(pc),a2
- bra DoFunc
-
- RestoreScreen:
-
- ;Enter with global in A1 AND input event in A0.
- move.l ie_TimeStamp(a0),ScreenTime(a1)
- bclr #STB_SBlanked,Status(a1)
- beq _RTS
- lea DoRestoreScreen(pc),a2
- ; bra DoFunc
-
- DoFunc:
-
- ;Enter with pointer to routine in A2
- ;Enter with global ptr in A1.
-
- movem.l d0-d1/a0-a1/a6,-(sp)
- lea TaskQueue(a1),a0
- moveq #MAXQUEUE-1,d0
- .. tst.l (a0)+
- dbeq d0,..
- bne .End
- move.l a2,-(a0)
- move.l FuncSig(a1),d0
- move.l Task(a1),a1
- move.l 4,a6
- SYS Signal
- .End: movem.l (sp)+,d0-d1/a0-a1/a6
- _RTS: rts
-
- ;**************************** Input handler *********************************
-
- IntRoutine:
- movem.l d2/a2/a6,-(sp)
- move.l a0,-(sp)
- move.l IntBase(a1),a6
- bsr GetIBase
-
- ;Handle NoFlicker option
- tst.l FlickerOption(a1)
- beq .SkipFlick
- move.l GraphBase(a1),a0
- move.l gb_LOFlist(a0),a2
- move.l WaitLineAddress(a1),a0
- cmp.b #WaitLine-1,WindowStart(a2)
- blo .DisableNF
- move.b #WaitLine,(a0)
- bra .SkipDisableNF
- .DisableNF:
- clr.b (a0)
- .SkipDisableNF:
- move.l GraphBase(a1),a0
- move.l gb_copinit(a0),a0
- cmp.w #color,SysBackground-2(a0)
- bne .DefColor
- move.w SysBackground(a0),d0
- move.l RealBackground(a1),a0
- move.w d0,(a0)
- bra .SkipColor
- .DefColor:
- move.l RealBackground(a1),a0
- move.w #DefColor,(a0)
- .SkipColor:
- move.l (sp),a0
- .SkipFlick:
-
- ;Check for change in active screen.
- ;But first: attempt to obtain the semaphores
- movem.l a0-a1/a6,-(sp)
- move.l 4,a6
- lea Semaphores(a1),a2
- moveq #NumSemaphores-1,d2
- .Attempt: move.l a2,a0
- SYS AttemptSemaphore
- tst.l d0
- beq .AttemptFailed
- lea SS_SIZE(a2),a2
- dbra d2,.Attempt
- movem.l (sp)+,a0-a1/a6
- bra .CheckScreenStuff
- .AttemptFailed:
- moveq #2,d0
- sub.w d2,d0
- bmi .NoneSucceeded
- move.l a2,a0
- .CleanUp: lea -SS_SIZE(a0),a0
- SYS ReleaseSemaphore
- dbra d0,.CleanUp
- .NoneSucceeded:
- movem.l (sp)+,a0-a1/a6
- bra .NoSemaphore
-
- .CheckScreenStuff:
- move.l CurrentActiveScreen(a1),d0
- cmp.l ib_ActiveScreen(a6),d0
- beq .SameActiveScreen
- push a0
- move.l CurrentActiveScreen(a1),a0
- move.l CurrentActiveWindow(a1),a2
- bsr RememberWindow
- pop a0
- .SameActiveScreen:
-
- ;Check for change in top screen.
- move.l CurrentTopScreen(a1),d0
- beq .CSZ
- cmp.l ib_FirstScreen(a6),d0
- beq .SkipRW
- push a0
- move.l CurrentActiveScreen(a1),a0
- move.l CurrentActiveWindow(a1),a2
- bsr RememberWindow
- pop a0
- lea TaskRestoreWindow(pc),a2
- bsr DoFunc
- .CSZ: move.l ib_FirstScreen(a6),CurrentTopScreen(a1)
- .SkipRW: move.l ib_ActiveWindow(a6),CurrentActiveWindow(a1)
- move.l ib_ActiveScreen(a6),CurrentActiveScreen(a1)
- bsr FreeAllSemaphores
- .NoSemaphore:
-
- ;If screen is blanked, re-blank (actually just move the blanking screen to the
- ;front)
- btst #STB_SBlanked,Status(a1)
- beq .SkipReBlank
- move.l ib_FirstScreen(a6),d0
- cmp.l BlankScreenPtr(a1),d0
- beq .SkipReBlank
- bsr BlankScreen
- .SkipReBlank:
-
- ;Re-blank mouse if a new window has been activated.
- move.l MBlankWindow(a1),d0
- beq .Loop
- cmp.l ib_ActiveWindow(a6),d0
- beq .EndMBW
- lea BlankMouse(pc),a2
- bsr DoFunc
- .EndMBW:
-
- .Loop: cmp.b #IECLASS_TIMER,ie_Class(a0)
- beq .Timer
-
- cmp.b #IECLASS_RAWKEY,ie_Class(a0)
- bne .NotKey
- tst.b ie_Code+1(a0)
- bmi .Next ;ignore up key codes
-
- bsr RestoreScreen
-
- ;Handle immediate blank feature
- tst.l ImmBlankOption(a1)
- beq .SkipImmBlank
- ;Check for lamiga+ramiga
- cmp.b #IEQUALIFIER_LCOMMAND+IEQUALIFIER_RCOMMAND,ie_Qualifier+1(a0)
- bne .SkipImmBlank
- bsr BlankScreen
- .SkipImmBlank:
-
- ;Perform SunKey
- tst.l SunKeyOption(a1)
- beq .SkipSKey
- lea ActivateWindow(pc),a2
- bsr DoFunc
- .SkipSKey:
-
- ;Do Northgate keyboard mapping.
- tst.l NorthGateOption(a1)
- beq .SkipNorthgate
- lea NorthgateTable(pc),a2
- move.w ie_Code(a0),d0
- bclr #7,d0
- .NorthgateLoop:
- move.b (a2),d1
- beq .EndNorthgate
- addq.l #3,a2
- cmp.b d0,d1
- bne .NorthgateLoop
- and.w #$80,ie_Code(a0)
- move.b -2(a2),d0
- or.b d0,ie_Code+1(a0)
- move.b -1(a2),d0
- bmi .EndNorthgate
- bset d0,ie_Qualifier+1(a0)
- .EndNorthgate:
- .SkipNorthgate:
-
- btst #IEQUALIFIERB_LCOMMAND,ie_Qualifier+1(a0)
- bne .DoLAmiga
-
- ;Blank mouse pointer
- tst.l MBlankOption(a1)
- beq .NoMBlank
- lea BlankMouse(pc),a2
- bsr DoFunc
- .NoMBlank:
- bra .Next
-
- .DoLAmiga:
- tst.l CmdOption(a1)
- beq .Next
- cmp.w #$45,ie_Code(a0) ;ESC?
- bne .Next
- clr.b ie_Class(a0)
- lea PopCLI(pc),a2
- bsr DoFunc
- bra .End
-
- .NotKey: bsr RestoreScreen
- .Timer: move.w ib_MouseX(a6),d0
- move.w ib_MouseY(a6),d1
- cmp.b #IECLASS_RAWMOUSE,ie_Class(a0)
- beq .DoMouse
- cmp.w CurrentX(a1),d0
- bne .DoMouse
- cmp.w CurrentY(a1),d1
- beq .Next
-
- .DoMouse:
- move.w d0,CurrentX(a1)
- move.w d1,CurrentY(a1)
- tst.l MBlankOption(a1)
- beq .NoRestore
- move.l ie_TimeStamp(a0),MouseTime(a1)
- lea RestoreMouse(pc),a2
- bsr DoFunc
- .NoRestore:
-
- ;Perform SunMouse
- tst.l SunMouseOption(a1)
- beq .SkipSunMouse
- move.w ie_Qualifier(a0),d0
- and.w #IEQUALIFIER_LEFTBUTTON+IEQUALIFIER_RBUTTON+IEQUALIFIER_MIDBUTTON,d0
- bne .SkipSunMouse
- cmp.w #IECODE_LBUTTON+IECODE_UP_PREFIX,ie_Code(a0)
- beq .SkipSunMouse
- move.l SunMouseDelayOption(a1),a2
- move.l a2,d0
- beq .SkipLoad
- move.l (a2),d0
- .SkipLoad:
- addq.l #1,d0
- move.l d0,SunMouseDelay(a1)
- .SkipSunMouse:
-
- ;Perform click-to-back.
- cmp.w #IECODE_RBUTTON,ie_Code(a0)
- bne .NoCTB
- move.w ie_Qualifier(a0),d0
- btst #IEQUALIFIERB_LEFTBUTTON,d0
- beq .DoSunRMB
- tst.l STBOption(a1)
- bne .DoCTB
- tst.l CTBOption(a1)
- beq .NoCTB
- .DoCTB: lea CTB(pc),a2
- bsr DoFunc
- clr.b ie_Class(a0)
- bra .Next
-
- .DoSunRMB:
-
- ;Perform SunRMB
- tst.l SunRMBOption(a1)
- beq .SkipSunRMB
- lea ActivateWindow(pc),a2
- bsr DoFunc
- .SkipSunRMB:
-
- .NoCTB:
-
- ;Perform click-to-front.
- tst.l CTFOption(a1)
- beq .NoCTF
- cmp.w #IECODE_LBUTTON,ie_Code(a0)
- bne .NoCTF
- btst #IEQUALIFIERB_LCOMMAND,ie_Qualifier+1(a0)
- bne .NoCTF ;to avoid interferring with Snap
- lea CTF(pc),a2
- bsr DoFunc
- .NoCTF:
-
- ;Perform acceleration.
- tst.l AccelOption(a1)
- beq .Next
-
- move.l ThreshOption(a1),d0
- beq .T1
- move.l d0,a2
- move.l (a2),d0
- .T1: move.w ie_X(a0),d1
- bpl .PosX
- neg.w d1
- .PosX: cmp.w d0,d1
- bls .SkipX ;below threshold
- move.l AccelOption(a1),a2
- move.l (a2),d1
- muls.w ie_X(a0),d1
- tst.w ie_X(a0)
- bpl .SubDampX
- add.w DampingConstant(a1),d1
- bra .DampX
- .SubDampX:
- sub.w DampingConstant(a1),d1
- .DampX: move.w d1,ie_X(a0)
- .SkipX: move.w ie_Y(a0),d1
- bpl .PosY
- neg.w d1
- .PosY: cmp.w d0,d1
- bls .EndAccel
- move.l AccelOption(a1),a2
- move.l (a2),d1
- muls.w ie_Y(a0),d1
- tst.w ie_Y(a0)
- bpl .SubDampY
- add.w DampingConstant(a1),d1
- bra .DampY
- .SubDampY:
- sub.w DampingConstant(a1),d1
-
- .DampY: move.w d1,ie_Y(a0)
- .EndAccel:
-
- .Next: move.l a0,d1
- move.l (a0),d0
- move.l d0,a0
- bne .Loop
-
- ;Check for time-outs (mouse and screen blanking)
- move.l d1,a0
- tst.l MBlankOption(a1)
- beq .NoMTime
- tst.l MBlankWindow(a1)
- bne .NoMTime
- move.l MBlankOption(a1),a0
- move.l (a0),d0 ;get value in seconds
- move.l d1,a0
- move.l ie_TimeStamp(a0),d1
- tst.l MouseTime(a1)
- beq .InitMBlank
- sub.l MouseTime(a1),d1
- cmp.l d0,d1 ;TimePassed ? UserSetting
- blo .NoMTime
- lea BlankMouse(pc),a2
- bsr DoFunc
- .NoMTime:
- tst.l SBlankOption(a1)
- beq .End
- btst #STB_SBlanked,Status(a1)
- bne .End
- push a0
- move.l SBlankOption(a1),a0
- move.l (a0),d0 ;get value in seconds
- pop a0
- move.l ie_TimeStamp(a0),d1
- tst.l ScreenTime(a1)
- beq .InitSBlank
- sub.l ScreenTime(a1),d1
- cmp.l d0,d1 ;TimePassed ? UserSetting
- blo .End
- bsr BlankScreen
-
- .End: bsr FreeIBase
- move.l (sp)+,d0
- movem.l (sp)+,d2/a2/a6
- rts
- .InitMBlank:
- move.l ie_TimeStamp(a0),MouseTime(a1)
- bra .NoMTime
- .InitSBlank:
- move.l ie_TimeStamp(a0),ScreenTime(a1)
- bra .End
-
- ;Enter with global pointer in A1.
- ;d0, d1, a0, a1, a5, and a6 are scratch.
- ;Must always end with a "moveq #0,d0" to set the Z flag.
-
- VBlankRoutine:
- tst.l SunMouseDelay(a1)
- beq .End
- subq.l #1,SunMouseDelay(a1)
- bne .End
- move.l a2,-(sp)
- lea ActivateWindow(pc),a2
- bsr DoFunc
- move.l (sp)+,a2
- .End: moveq #0,d0
- rts
-
- GlobalPtr:
- dc.l 0
-
- NorthgateTable:
- ;Assign PageUp/PageDown/Home/End to shift-cursor sequences
- dc.b $6b,$4f,IEQUALIFIERB_LSHIFT
- dc.b $6c,$4e,IEQUALIFIERB_LSHIFT
- dc.b $6d,$4c,IEQUALIFIERB_LSHIFT
- dc.b $6e,$4d,IEQUALIFIERB_LSHIFT
-
- ;Change a couple keypad key assignments to be more Amiga-like.
- dc.b $5c,$5b,0 ;'/' key -> ')' key
- dc.b $5d,$5c,0 ;'*' key -> '/' key
- dc.b $4a,$5d,0 ;'-' key -> '*' key
- dc.b 0
-
- ProcName: dc.b 'QMouse process',0
- InputName:
- dc.b 'input.device',0
- TrackName:
- dc.b 'trackdisk.device',0
- even
-
- ;*************************** Debugging stuff *************************
-
- IFNE INFO_LEVEL
- KPutFmt: movem.l a2/a6,-(sp)
- move.l 4,a6
- lea KPutChar(pc),a2
- SYS RawDoFmt
- movem.l (sp)+,a2/a6
- rts
-
- KPutChar:
-
- ;Serial
- comment |
- move.l a6,-(sp)
- move.l 4,a6
- SYS RawPutChar
- move.l (sp)+,a6
- rts
- |
-
- ;Printer
- comment |
- move.b #$ff,$bfe301
- .Print: btst #0,$bfd000
- bne .Print
- move.b d0,$bfe101
- rts
- |
-
- ;Memory
- movem.l a0-a1,-(sp)
- lea MemPtr(pc),a1
- move.l (a1),a0
- move.b d0,(a0)+
- move.l a0,(a1)
- movem.l (sp)+,a0-a1
- rts
- MemPtr: dc.l $300000
- ENDC
-
- EndAllocCode: ;end of code copied into allocated memory
- ;***********************************************************************
-
- NewProcTags:
- dc.l NP_Entry
- EntryPoint:
- dc.l 0
- dc.l NP_Name
- ProcNamePtr:
- dc.l 0
- dc.l NP_Cli,-1
- dc.l NP_Priority,TaskPriority
- dc.l 0 ;end of tags
-
- Template: dc.b 'M=MBLANK/K/N,'
- dc.b 'S=SBLANK/K/N,'
- dc.b 'N=NOFLICKER/S,'
- dc.b 'CMD/K,'
- dc.b 'A=ACCELERATION/K/N,'
- dc.b 'T=THRESHOLD/K/N,'
- dc.b 'CTB=CLICKTOBACK/S,'
- dc.b 'STB=SCREENTOBACK/S,'
- dc.b 'CTF=CLICKTOFRONT/K/N,'
- dc.b 'SUNMOUSE/S,'
- dc.b 'SUNKEY/S,'
- dc.b 'NORTHGATE/S,'
- dc.b 'NOBEEP/S,'
- dc.b 'NOCLICK/K/N,'
- dc.b 'VERIFY/S,'
- dc.b 'NOVERIFY/S,'
- dc.b 'STAR/S,'
- dc.b 'NoWBenchToFront/S,'
- dc.b 'PUBCHANGE/S,'
- dc.b 'SunMouseDelay/K/N,'
- dc.b 'ImmBlank/S,'
- dc.b 'NoActivate/S,'
- dc.b 'SunRMB/S,'
- dc.b 'QUIT/S',0
-
- IntName: dc.b 'intuition.library',0
- GraphName:
- dc.b 'graphics.library',0
- DosName: dc.b 'dos.library',0
- LayersName:
- dc.b 'layers.library',0
- UtilityName:
- dc.b 'utility.library',0
- BadArgs: dc.b 'Bad arguments.',$a,0
-
- dc.b '$VER: QMouse 2.90 (4.1.94)',$a,0
-
- ;The ordering here is special: data registers first, then address
- ;registers, so that MOVEM may be used to save/restore the data.
-
- STRUCTURE pt,0
- LONG pt_Height
- LONG pt_Width
- LONG pt_XOffset
- LONG pt_YOffset
- LONG pt_Window
- LONG pt_Pointer
- BYTE TagVersion ;special boolean indicator
- BYTE pt_pad
- LABEL pt_Sizeof
-
- ResidentCodeSize equ EndAllocCode-StartAllocCode
-
- STRUCTURE Data,0
- WORD Nothing ;to make zero special
-
- LABEL Sigs
- LONG QuitSig
- LONG FuncSig
- LABEL EndSigs
-
- LABEL Semaphores
- STRUCT MySemaphore,SS_SIZE
- STRUCT CloseWindowSemaphore,SS_SIZE
- STRUCT CloseScreenSemaphore,SS_SIZE
- STRUCT CloseWBSemaphore,SS_SIZE
- LABEL EndSemaphores
-
- LONG Task
- LONG InputMsgPort
- LONG InputIORequest
- STRUCT InputInterrupt,IS_SIZE
- LONG IntBase
- LONG GraphBase
- LONG LayersBase
- LONG _UtilityBase
- STRUCT ScreenList,SCREENLISTSIZE*8
- STRUCT PointerList,POINTERLISTSIZE*pt_Sizeof
- STRUCT TaskQueue,MAXQUEUE*4+4
- LONG OldCloseScreen
- LONG OldCloseWorkBench
- LONG OldCloseWindow
- LONG OldSetPointer
- LONG OldSetWindowPointerA
- LONG OldClearPointer
- LONG OldDisplayBeep
- LONG OldOpenWindowTagList
- LONG DosBase
- LONG ArgPtr
- STRUCT ResidentCode,ResidentCodeSize
- LONG MouseTime ;timeout for mouse blanking
- LONG ScreenTime ;for screen blanking
- LONG BlankScreenPtr
- LONG BlankScreenWindowPtr
- LONG MBlankWindow
- WORD DampingConstant
- LONG ClickWindow
- STRUCT ClickTime,TV_SIZE
- LONG ClickCount
- LONG Path
- LONG ChipData
- LONG RealBackground
- LONG OriginalCopInit
- WORD CurrentX
- WORD CurrentY
- LONG WaitLineAddress
- LONG CurrentTopScreen
- LONG CurrentActiveScreen
- LONG CurrentActiveWindow
- LONG SunMouseDelay
- STRUCT VBlankServer,IS_SIZE
- LONG IBaseLock
-
- LABEL Options
- LONG MBlankOption
- LONG SBlankOption
- LONG FlickerOption
- LONG CmdOption
- LONG AccelOption
- LONG ThreshOption
- LONG CTBOption
- LONG STBOption
- LONG CTFOption
- LONG SunMouseOption
- LONG SunKeyOption
- LONG NorthGateOption
- LONG BeepOption
- LONG NoClickOption
- LONG VerifyOption
- LONG NoVerifyOption
- LONG StarOption
- LONG NoWBenchToFrontOption
- LONG PubChangeOption
- LONG SunMouseDelayOption
- LONG ImmBlankOption
- LONG NoActivateOption
- LONG SunRMBOption
- LONG QuitOption
-
- BYTE HandlerInstalled
- BYTE Status ;various status bits (defined below)
- LABEL Data_Sizeof
-
- ;Bit definitions for Status
- BITDEF ST,SBlanked,0
- BITDEF ST,IntInstalled,1
-
- NumSigs equ (EndSigs-Sigs)/4
- NumSemaphores equ (EndSemaphores-Semaphores)/SS_SIZE
-
- STRUCTURE CData,0
- STRUCT ZeroMouse,12
- STRUCT Copper,MaxCopperSize+4*4
- LABEL CData_Sizeof
-
- end
-